#include "stm32f10x.h"                  // Device header


/************************************************************************************************************
* Function name : MySPI_W_SS
* Description   : 拉高 或 拉低 SS 线
* Parameter     : 
* Return        : 
************************************************************************************************************/
void MySPI_W_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}


/************************************************************************************************************
* Function name : MySPI_W_SCK
* Description   : 拉高 或 拉低 CLK 线
* Parameter     : 
* Return        : 
************************************************************************************************************/
void MySPI_W_SCK(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);
}


/************************************************************************************************************
* Function name : MySPI_W_MOSI 
* Description   : 拉高 或 拉低 MOSI 线
* Parameter     : 
* Return        : 
************************************************************************************************************/
void MySPI_W_MOSI(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);
}


/************************************************************************************************************
* Function name : MySPI_R_MISO
* Description   : 读取 MISO 的高低电平
* Parameter     : 
* Return        : 
************************************************************************************************************/
uint8_t MySPI_R_MISO()
{
	return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
}


/************************************************************************************************************
* Function name : MySPI_Init
* Description   : 初始化 SPI 的通信引脚
* Parameter     : 
* Return        : 
************************************************************************************************************/
void MySPI_Init(void)
{
	// 打开 APB2 的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	// 输出引脚 CS, CLK, MOSI 均需配置成推挽输出
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                     // 推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;  // 选择引脚, 分别为 CS, 时钟, MISO, MOSI
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                    // 输出速度没有特殊要求选择 50MHz 即可
	GPIO_Init(GPIOA, &GPIO_InitStructure);    
	
	// 输入引脚 MISO 配置成浮空 或 上拉即可
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_Init(GPIOA, &GPIO_InitStructure); 
	
	// 置一下初始化引脚的默认电平: 
	// SS 置为高电平,  SCK 在模式0时默认低电平, MOSI 无规定, MISO 输入引脚不用管
	MySPI_W_SS(1);
	MySPI_W_SCK(0);
}


/************************************************************************************************************
* Function name : MySPI_Start
* Description   : 起始信号, SS 置为低电平即可
* Parameter     : 
* Return        : 
************************************************************************************************************/
void MySPI_Start(void)
{
	MySPI_W_SS(0);
}


/************************************************************************************************************
* Function name : MySPI_Start
* Description   : 终止信号, SS 置为高电平即可
* Parameter     : 
* Return        : 
************************************************************************************************************/
void MySPI_Stop(void)
{
	MySPI_W_SS(1);
}


/************************************************************************************************************
* Function name : MySPI_SwapByte
* Description   : 交换字节 
* Parameter     : 
* Return        : 
************************************************************************************************************/
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
	uint8_t i = 0;
	for(i = 0; i < 8; i++)
	{
		// 移出寄存器 B7
		MySPI_W_MOSI(ByteSend & 0x80);
		ByteSend <<= 1;
		 
		// 移入寄存器 B7
		MySPI_W_SCK(1);
		if(MySPI_R_MISO() == 1)
		{
			ByteSend |= 0x01;
		}
		MySPI_W_SCK(0);
	}
	
	// 结束时候 MOSI 电平为低电平
	return ByteSend;
}